package com.yj.music_center.util.audio;

import android.content.Context;
import android.media.AudioManager;
import android.media.AudioPlaybackConfiguration;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.view.KeyEvent;

import androidx.annotation.NonNull;

import com.yj.music_center.callback.impl.CallbackImpl;
import com.yj.music_center.util.log.Logger;

import java.lang.ref.WeakReference;
import java.util.List;

public class AudioUtil {

    private static final String TAG = AudioUtil.class.getName();


    private AudioUtil(){};
    private static AudioUtil audioUtil;
    public static AudioUtil getInstance(){
        if(audioUtil == null){
           synchronized (AudioUtil.class){
               audioUtil = new AudioUtil();
           }
        }
        return audioUtil;
    }

    private AudioManager audioManager;
    private Handler handler;

    private AudioManager.AudioPlaybackCallback callback;

    private long last = 0;

    public void init(@NonNull WeakReference<Context> contextWeakReference){
        try {
            Context context = contextWeakReference.get();
            if(context != null){
                audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

                handler = new Handler(Looper.getMainLooper());
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    callback = new AudioManager.AudioPlaybackCallback() {
                        @Override
                        public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
                            super.onPlaybackConfigChanged(configs);


                            long now = System.currentTimeMillis();
                            if(now - last < 200){
                                last = now;
                                Logger.d(TAG, "onPlaybackConfigChanged gap too short");
                            }else{
                                last = now;
                                Logger.d(TAG, "onPlaybackConfigChanged delay 1s");
                                handler.removeCallbacksAndMessages(null);
                                handler.postDelayed(()->{
                                    CallbackImpl.getInstance().onPlaybackConfigChanged(isMusicActive());
                                }, 1000);
                            }


                        }
                    };
                    audioManager.registerAudioPlaybackCallback(callback, handler);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void playOrPauseMusic() {
        sendMediaButton(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
    }

    public void nextMusic(){
        sendMediaButton(KeyEvent.KEYCODE_MEDIA_NEXT);
    }

    public void lastMusic(){
        sendMediaButton(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
    }

    public boolean isMusicActive(){
        try{
            Logger.d(TAG, "called isMusicActive");
            if(audioManager == null){
                Logger.d(TAG, "audioManager is null");
                return false;
            }
            return audioManager.isMusicActive();
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    private void sendMediaButton(int keyCode) {
        try {
            if(audioManager == null){
                Logger.d(TAG, "audioManager is null");
                return;
            }
            Logger.d(TAG, "key down");
            KeyEvent keyEventDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
            audioManager.dispatchMediaKeyEvent(keyEventDown);

            Logger.d(TAG, "key up");
            KeyEvent keyEventUp = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
            audioManager.dispatchMediaKeyEvent(keyEventUp);
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    public void close(){
        try {
            handler.removeCallbacksAndMessages(null);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if(audioManager != null){
                    if(callback != null){
                        audioManager.unregisterAudioPlaybackCallback(callback);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
